#include "Man.h"
#include "Globals.h"
#include "Monster.h"

#include <gtest/gtest.h>

#include <iostream>

using namespace std;

//GLOBALS
Man *testMan = NULL;
Monster *testMonster = NULL;

//--------------------------------------------
//1. MOVEMENT
//--------------------------------------------

//TEST 1.1:   Does the testMan object get initialised to the
//          centre of the screen
TEST(Man, testManInitToCentreOfScreen)
{
    testMan = new Man();
    testMan -> initialise();
    int midScreen_x = 650;  //horizontal centre of the screen
    int midScreen_y = 350;  //vertical centre of the screen

    EXPECT_TRUE ( midScreen_x == testMan->get_pos_x() &&  midScreen_y == testMan->get_pos_y() );
    delete testMan;
}

//TEST 1.2:   Does testMan move up
TEST(Man, testManMovesUp)
{
    testMan = new Man();
    testMan -> initialise();
    int expected_pos_x = 650;
    int expected_pos_y = 345;   //moves up by 5 because _speed_y = 5
    testMan -> move_up();
    //testMan -> possition_check;
    testMan -> update();

    EXPECT_TRUE ( expected_pos_x == testMan->get_pos_x() && expected_pos_y == testMan->get_pos_y());
    delete testMan;
}

//TEST 1.3:   Does testMan move down
TEST(Man, testManMovesDown)
{
    testMan = new Man();
    testMan -> initialise();
    int expected_pos_x = 650;
    int expected_pos_y = 355;   //moves down by 5 because _speed_y = 5
    testMan -> move_down();
   // testMan -> possition_check();
    testMan -> update();

    EXPECT_TRUE ( expected_pos_x == testMan->get_pos_x() && expected_pos_y == testMan->get_pos_y());
    delete testMan;
}

//TEST 1.4:   Does testMan move left
TEST(Man, testManMovesLeft)
{
    testMan = new Man();
    testMan -> initialise();
    int expected_pos_x = 645;
    int expected_pos_y = 350;   //moves left by 5 because _speed_x = 5
    testMan -> move_left();
  //  testMan -> possition_check();
    testMan -> update();

    EXPECT_TRUE ( expected_pos_x == testMan->get_pos_x() && expected_pos_y == testMan->get_pos_y());
    delete testMan;
}

//TEST 1.5:   Does testMan move right
TEST(Man, testManMovesRight)
{
    testMan = new Man();
    testMan -> initialise();
    int expected_pos_x = 655;
    int expected_pos_y = 350;   //moves right by 5 because _speed_x = 5
    testMan -> move_right();
   // testMan -> possition_check();
    testMan -> update();

    EXPECT_TRUE ( expected_pos_x == testMan->get_pos_x() && expected_pos_y == testMan->get_pos_y());
    delete testMan;
}

//Note: game screen = 1250x650

//TEST 1.6:   Does testMan go over the top edge of the game screen
TEST(Man, testManGoesOverTopEdgeOfGameScreen)
{
    testMan = new Man();
    testMan -> initialise();
    testMan -> set_pos_y(0);    //moves testMan to possition (650,0) from (650, 350)
    testMan -> move_up();
   // testMan -> possition_check();
    testMan -> update();

    EXPECT_FALSE (testMan->get_pos_y() < 0);
    delete testMan;
}

//TEST 1.7: Does testMan stay at the top edge of the game screen
//          when asked to go further up
TEST(Man, testManStaysAtTopEdgeOfGameScreen)
{
    testMan = new Man();
    testMan -> initialise();
    testMan -> set_pos_y(100);    //moves testMan to possition (650,100) from (650, 350)
    testMan -> move_up();
  //  testMan -> possition_check();
    testMan -> update();

    EXPECT_TRUE (testMan->get_pos_y() == 100);
    delete testMan;
}

//TEST 1.8: Does testMan go over the bottom edge of the game screen
TEST(Man, testManGoesOverBottomEdgeOfGameScreen)
{
    testMan = new Man();
    testMan -> initialise();
    testMan -> set_pos_y(650);
    testMan -> move_down();
  //  testMan -> possition_check();
    testMan -> update();

    EXPECT_FALSE (testMan->get_pos_y() > 650);
    delete testMan;
}

//TEST 1.9: Does testMan stay at the bottom edge of the game screen
//          when asked to go further down
TEST(Man, testManStaysAtBottomEdgeOfGameScreen)
{
    testMan = new Man();
    testMan -> initialise();
    testMan -> set_pos_y(650);
    testMan -> move_down();
   // testMan -> possition_check();
    testMan -> update();

    EXPECT_TRUE (testMan->get_pos_y() == 650);
    delete testMan;
}

//TEST 1.10: Does testMan go over the right edge of the game screen
TEST(Man, testManGoesOverRightEdgeOfGameScreen)
{
    testMan = new Man();
    testMan -> initialise();
    testMan -> set_pos_x(1250);
    testMan -> move_right();
 //   testMan -> possition_check();
    testMan -> update();

    EXPECT_FALSE (testMan->get_pos_x() > 1250);
    delete testMan;
}

//TEST 1.11: Does testMan stay at the right edge of the game screen
//           when asked to go further right
TEST(Man, testManStaysAtRightEdgeOfGameScreen)
{
    testMan = new Man();
    testMan -> initialise();
    testMan -> set_pos_x(1250);
    testMan -> move_right();
  //  testMan -> possition_check();
    testMan -> update();

    EXPECT_TRUE (testMan->get_pos_x() == 1250);
    delete testMan;
}

////////////////

//TEST 1.12: Does testMan go over the left edge of the game screen
TEST(Man, testManGoesOverLeftEdgeOfGameScreen)
{
    testMan = new Man();
    testMan -> initialise();
    testMan -> set_pos_x(0);
    testMan -> move_left();
  //  testMan -> possition_check();
    testMan -> update();

    EXPECT_FALSE (testMan->get_pos_x() < 0);
    delete testMan;
}

//TEST 1.13: Does testMan stay at the left edge of the game screen
//           when asked to go further left
TEST(Man, testManStaysAtLeftEdgeOfGameScreen)
{
    testMan = new Man();
    testMan -> initialise();
    testMan -> set_pos_x(0);
    testMan -> move_left();
  //  testMan -> possition_check();
    testMan -> update();

    EXPECT_TRUE (testMan->get_pos_x() == 0);
    delete testMan;
}

//------------------------------------------
//2. Monster
//------------------------------------------

//Test 2.1 : Monster is initialized on the screen
TEST(Monster, monsterInitializedOnScreen)
{
    testMonster = new Monster();
    testMonster->initialize(150, 500);

    int xCoord = 150;
    int yCoord = 500;

    EXPECT_TRUE( xCoord == testMonster->get_xPos() && yCoord == testMonster->get_yPos());
    delete testMonster;
}
//Test 2.2: Monster can move right
TEST(Monster, monsterMovesRight )
{
    testMonster = new Monster();
    testMonster->initialize(150,500);
    testMonster->move_right();

    int newX = 152.5;  //speed = 2.5;
    int newY = 500;

    EXPECT_TRUE(newX == testMonster->get_xPos() && newY == testMonster->get_yPos());
    delete testMonster;

}

//Test 2.3: Monster can move left
TEST(Monster, monsterMoveLeft )
{
    testMonster = new Monster();
    testMonster->initialize(150,500);
    testMonster->move_left();

    int newX = 147.5;
    int newY = 500;

    EXPECT_TRUE(newX == testMonster->get_xPos() && newY == testMonster->get_yPos());
    delete testMonster;

}
//Test 2.4: Monster moves up
TEST(Monster, monsterMovesUp )
{
    testMonster = new Monster();
    testMonster->initialize(150,500);
    testMonster->move_up();

    int newX = 150;  //speed = 2.5;
    int newY = 497.5;

    EXPECT_TRUE(newX == testMonster->get_xPos() && newY == testMonster->get_yPos());
    delete testMonster;

}
//Test 2.5: Monster moves down
TEST(Monster, monsterMovesDown )
{
    testMonster = new Monster();
    testMonster->initialize(150,500);
    testMonster->move_down();

    int newX = 150;  //speed = 2.5;
    int newY = 502.5;

    EXPECT_TRUE(newX == testMonster->get_xPos() && newY == testMonster->get_yPos());
    delete testMonster;

}
//-----------------Monster following Man object---------------------

//Test 2.6: Monster is aware of testMan's position
TEST(Monster, monsterIsAwareOfManInitialPosition )
{
    testMonster = new Monster();
    testMan = new Man();
    testMonster->initialize(150,500);
    testMan->initialise();

    testMonster->follow_digdugX( testMan );
    testMonster->follow_digdugY( testMan );

    int testManX = testMan->get_pos_x();
    int testManY = testMan->get_pos_y();

    EXPECT_TRUE(testManX == testMonster->get_digdugX() && testManY == testMonster->get_digdugY());
    delete testMonster;
    delete testMan;

}
//Test 2.7: Monster is aware if testMan's position changes
TEST(Monster, monsterIsAwareOfChangeInManPosition )
{
    testMonster = new Monster();
    testMan = new Man();
    testMonster->initialize(150,500);
    testMan->initialise();

    testMan->move_down();   //moving man around
    testMan->move_left();
    testMan->move_down();

    testMonster->follow_digdugX( testMan );
    testMonster->follow_digdugY( testMan );

    int testManX = testMan->get_pos_x();
    int testManY = testMan->get_pos_y();

    EXPECT_TRUE(testManX == testMonster->get_digdugX() && testManY == testMonster->get_digdugY());
    delete testMonster;
    delete testMan;

}

TEST(ExitTest, )
{
    system("Pause");
}



